#include <iostream>
#include <sstream>

#include "ShaderProgram.h"

using namespace std;

ShaderProgram::ShaderProgram() {}

void ShaderProgram::build() {
	if (glIsProgram(handle) == GL_TRUE)
		glDeleteProgram(handle);

	handle = glCreateProgram();
	//cout << "Building shader program..." << endl;
	for (unsigned int i = 0; i < shaders.size(); i++) {
		shaders[i]->compile();
		glAttachShader(handle, shaders[i]->getHandle());
	}
	//cout << "Linking shader program..." << endl;
	glLinkProgram(handle);

	int linkResult;
	glGetProgramiv(handle, GL_LINK_STATUS, &linkResult);
	if (linkResult == GL_TRUE) {
		//cout << "Successfully linked." << endl;
	} else {
		stringstream msg;

		int length;
		glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &length);
		char log[1024];
		glGetProgramInfoLog(handle, length, &length, log);

		msg << "Failed to link." << endl;
		msg << log << endl;

		//cout << msg.str();
	}
}

void ShaderProgram::use() {
	glUseProgram(handle);
}

void ShaderProgram::addVertexShader(string path) {
	shaders.push_back(new Shader(GL_VERTEX_SHADER, path));
}

void ShaderProgram::addFragmentShader(string path) {
	shaders.push_back(new Shader(GL_FRAGMENT_SHADER, path));
}

ShaderProgram::~ShaderProgram() {
	for (unsigned int i = 0; i < shaders.size(); i++) {
		glDetachShader(handle, shaders[i]->getHandle());
		delete shaders[i];
	}
	if (glIsProgram(handle) == GL_TRUE)
		glDeleteProgram(handle);
	//cout << "Deleting shader program." << endl;
}
